package com.reform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.reform.config.JwtTokenUtil;
import com.reform.pojo.project.MyProjectInfo;
import com.reform.pojo.project.Project;
import com.reform.mapper.ProjectMapper;
import com.reform.pojo.project.ProjectStatus;
import com.reform.pojo.project.SimplifyProject;
import com.reform.res.Result;
import com.reform.res.ResultCode;
import com.reform.service.IProjectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.reform.service.IViewProjectService;
import com.reform.utils.JSONToArrUtils;
import com.reform.utils.JaroWinklerDistance;
import com.reform.utils.VerifycUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;
import java.util.*;

/**
 * <p>
 * 项目基本信息 服务实现类
 * </p>
 *
 * @author mortale
 * @since 2021-07-20
 */
@Service
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> implements IProjectService {

    @Autowired
    ProjectMapper projectMapper;
    @Autowired
    IViewProjectService viewProjectService;
    @Autowired
    JwtTokenUtil jwtTokenUtil;
    private static final float REPETITION_RATE = 0.6f;

    @Override
    public Integer creatProject(Project project) {
        return projectMapper.insert(project);
    }

    @Override
    public Integer deleteProject(String proId) {
        return projectMapper.deleteById(proId);
    }

    @Override
    public Integer updateProject(Project project) {
        return projectMapper.updateById(project);
    }

    @Override
    public Result nameRate(String batchId, String proId, String projectName, Float repetitionRate) throws SQLException {
        if (!VerifycUtils.verifyNullOrEmptyUtils(repetitionRate)) {
            repetitionRate = REPETITION_RATE;
        }
        List<Map<String, Object>> resList = new ArrayList<>();
        List<Project> allProject;
        allProject = projectMapper.selectList(new QueryWrapper<Project>().eq("batch_id", batchId).ne("pro_approval", -1).ne("pro_approval", 0)
                .ne("pro_id", proId));

        for (Project project : allProject) {
            //判断重复率
            float jaroDistance = JaroWinklerDistance.levenshtein(projectName, project.getProName());
            if (jaroDistance >= repetitionRate) {
                Map<String, Object> map = new HashMap<>();
                map.put("nameRepetitionRate", jaroDistance);
                map.put("ProName", project.getProName());
                map.put("ProId", project.getProId());
                resList.add(map);
            }
        }
        //排序
        resList.sort(Comparator.comparing(arg0 -> arg0.get("nameRepetitionRate").toString()));
        //list逆序
        Collections.reverse(resList);
        return Result.success(ResultCode.SUCCESS, resList);
    }

    @Override
    public Result getProjectsByGH(String gh) throws SQLException {
        return viewProjectService.getProjectsByGH(gh);
    }

    @Override
    public List<SimplifyProject> getInitiationInfo(String gh, Integer type) {
        return projectMapper.getInitiationInfo(gh, type);
    }

    /**
     * 1、批次编号
     * 2、批次名称
     * 3、项目名称
     * 4、项目级别
     * 5、项目当前状态
     * 6、阶段信息
     * 1、申报时间
     * 状态
     * 2、阶段检查 ****可能存在多个阶段检查，返回信息应为一个数组
     * 状态
     * 3、项目结题
     * 状态
     * <p>
     * 具体操作
     * 根据gh查询该教师主持的项目信息
     * 该操作可以获得批次编号、项目名称、项目编号、项目级别、项目当前状态
     * 根据批次查询
     * 该操作可以获得批次名称、阶段信息
     *
     * @return 简单项目信息数据列表
     */

    public List<MyProjectInfo> getSimplifyProjectsByGH(HttpServletRequest request, Integer ranking) {
        String token = request.getHeader("token");
        if (token == null) {
            return null;
        }
        String gh = jwtTokenUtil.getGHFromToken(token);
        return viewProjectService.getSimplifyProjectsByGH(gh, ranking);
    }

    @Override
    public Result getHostProjectsByGH(HttpServletRequest request) {
        List<MyProjectInfo> simplifyProjects = getSimplifyProjectsByGH(request, 1);
        if (!VerifycUtils.verifyNullOrEmptyUtils(simplifyProjects))
            return Result.failure(ResultCode.FAILURE);
        return Result.success(ResultCode.SUCCESS, simplifyProjects);
    }

    @Override
    public Result getPartakeProjectsByGH(HttpServletRequest request) {
        List<MyProjectInfo> simplifyProjects = getSimplifyProjectsByGH(request, -1);
        if (!VerifycUtils.verifyNullOrEmptyUtils(simplifyProjects))
            return Result.failure(ResultCode.FAILURE);
        return Result.success(ResultCode.SUCCESS, simplifyProjects);
    }


    @Override
    public Result updateProByProId(String proId, Integer proApproval, Integer proStatus) {
        projectMapper.updateProByProId(proId, proApproval, proStatus);
        return Result.success(ResultCode.SUCCESS);
    }

    @Override
    public Result updateProStatusByProId(String proId, Integer proStatus) {
        projectMapper.updateProStatusByProId(proId, proStatus);
        return Result.success(ResultCode.SUCCESS);
    }

    @Override
    public Result updateProsByProId(String projectStatus) {
        List<ProjectStatus> list = JSONToArrUtils.jsonToArr(projectStatus, ProjectStatus.class);
        if (!VerifycUtils.verifyNullOrEmptyUtils(list))
            return Result.failure(ResultCode.PARAM_JSON_IS_WRONG);
        assert list != null;
        for (ProjectStatus s : list) {
            projectMapper.updateProsByProId(s.getProId(), s.getProStatus(), s.getProApproval());
        }
        return Result.success(ResultCode.SUCCESS);
    }

    @Override
    public Result addDelayCauseByProId(String proId, String delayCause) {
        if (projectMapper.addDelayCauseByProId(proId, delayCause) > 0)
            return Result.success(ResultCode.SUCCESS);
        return Result.failure(ResultCode.FAILURE);
    }

    @Override
    public Result getDelayCauseByProId(String proId) {
        return Result.success(ResultCode.SUCCESS, projectMapper.getDelayCauseByProId(proId));
    }

    @Override
    public List<String> getProIdByBatchId(String batchId) {
        return projectMapper.getProIdByBatchId(batchId);
    }

    @Override
    public List<String> getBatchIdByApproval(int approval) {
        return projectMapper.getBatchIdByApproval(approval);
    }

}
